package customer.design.dispatcher.dispatchermode.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class FileUtils {
    private static final Logger logger = LoggerFactory.getLogger(FileUtils.class);

    public static void writeContentToDisk(String content, String diskPath, String zipPath, boolean flag) {
        long startTime = System.currentTimeMillis();
        FileWriter fileWriter = null;
        try {
            createFileDir(diskPath);
            File[] files = new File(diskPath).listFiles();
            if (files != null && files.length > 0) {
                List<File> fileList = Arrays.asList(files);
                if (fileList.size() > 1) {
                    //多个文件时，倒序排序
                    fileList.sort(((o1, o2) -> o2.getName().compareTo(o1.getName())));
                }
                File file = fileList.get(0);
                String newFileName = handleFile(diskPath, zipPath, file.getName(), flag);
                fileWriter = new FileWriter(diskPath + newFileName, true);
            } else {
                String fileName = createFileName(flag, DateUtil.PATTERN);
                fileWriter = new FileWriter(diskPath + fileName, true);
            }
            fileWriter.write(content);
            fileWriter.write(System.getProperty("line.separator"));
            fileWriter.flush();
            fileWriter.close();
        } catch (Exception e) {

        } finally {
            if (fileWriter != null) {
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    logger.info("文件写入异常");
                }
            }
        }

        logger.info("文件写入耗费时长为：{}", System.currentTimeMillis() - startTime);
    }

    public static String handleFile(String diskPath, String zipPath, String fileName, boolean flag) {
        String newHistoryDate = fileName.contains("_error") ? fileName.split("_error")[0] : fileName.split("\\.")[0];
        if (!isSameDay(newHistoryDate, DateUtil.PATTERN)) {
            //移动文件路径文件夹创建
            createFileDir(zipPath);
            //源文件路径
            String sourceFileName = diskPath + fileName;
            String zipPathName = zipPath + fileName.split("\\.")[0] + ".zip";
            //打包并移动文件
            packageZipFileAndMove(sourceFileName, zipPathName);
            return createFileName(flag, DateUtil.PATTERN);
        }
        return fileName;
    }

    public static String createFileName(boolean flag, String pattern) {
        DateFormat format = new SimpleDateFormat(pattern);
        String fileName = format.format(new Date());
        if (flag) {
            return fileName + "_error.log";
        }
        return fileName + ".log";
    }

    /**
     * 将文件打包为zip压缩包
     *
     * @param sourceFilePath 源文件路径+文件名
     * @param zipFilePath    zip文件路径+文件名
     */
    public static void packageZipFileAndMove(String sourceFilePath, String zipFilePath) {
        FileInputStream fileInputStream = null;
        ZipOutputStream zipOutputStream = null;
        File sourceFile = null;
        try {
            byte[] bytes = new byte[4096];
            fileInputStream = new FileInputStream(sourceFilePath);
            zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFilePath));
            sourceFile = new File(sourceFilePath);
            if (sourceFile.exists()) {
                zipOutputStream.putNextEntry(new ZipEntry(sourceFile.getName()));
                int length = 0;
                while ((length = fileInputStream.read(bytes)) > 0) {
                    zipOutputStream.write(bytes, 0, length);
                }
                zipOutputStream.flush();
                zipOutputStream.closeEntry();
                zipOutputStream.close();
            }

        } catch (Exception e) {
            logger.info("zip文件打包失败");
        } finally {
            if (zipOutputStream != null) {
                try {
                    zipOutputStream.close();
                } catch (IOException e) {
                    logger.info("关闭zipOutputStream流异常");
                }
            }
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    logger.info("关闭fileInputStream流异常");
                }
            }
            if (sourceFile != null) {
                if (sourceFile.delete()) {
                    logger.info("源文件删除成功");
                }
            }
        }
    }

    /**
     * 创建文件路径
     *
     * @param diskPath 路径
     */
    private static void createFileDir(String diskPath) {
        File file = new File(diskPath);
        if (file.exists()) {
            logger.info("文件路径已经存在");
        } else {
            if (file.mkdirs()) {
                logger.info("文件路径创建成功");
            }
        }
    }

    /**
     * 判断历史日期与现在是否是同一天
     *
     * @param historyDay 历史日期
     * @param pattern    格式
     * @return true / false
     */
    public static boolean isSameDay(String historyDay, String pattern) {
        try {
            DateFormat format = new SimpleDateFormat(pattern);
            Date date = format.parse(historyDay);
            Instant instant = date.toInstant();
            ZoneId zoneId = ZoneId.systemDefault();
            LocalDate historyLocalDate = LocalDateTime.ofInstant(instant, zoneId).toLocalDate();
            LocalDate currentLocalDate = LocalDate.now();
            int result = historyLocalDate.compareTo(currentLocalDate);
            if (result == 0) {
                return true;
            }
        } catch (Exception e) {
            logger.info("判断历史日期与当前日期是否是同一天失败");
        }
        return false;
    }
}
